<?php

namespace app\common\domain;

use app\common\enum\ExpressStatusEnum;
use app\common\exception\Client;
use think\facade\Config;

class Express
{

    const COMPANY_ABBR_MAP = [
        1 => 'SF',  // 顺丰
        2 => 'JD',  // 京东
        3 => 'STO', // 申通
        4 => 'YTO', // 圆通
        5 => 'ZTO', // 中通
        6 => 'YD',  // 韵达
        7 => 'JT',  // 极兔
        8 => 'EMS'  // 邮政
    ];
    // 快递单号规则（正则表达式）
    const TRACKING_RULES = [
        1 => '/^(SF|sf)[0-9]{13}$|^[0-9]{13}$/',      // 顺丰
        2 => '/^JD[0-9]{10}$|^[0-9]{18}$/',           // 京东
        3 => '/^(STO|sto)[0-9]{10}$|^[0-9]{12}$/',    // 申通
        4 => '/^(YTO|yto)[0-9]{10}$|^[0-9]{10,12}$/', // 圆通
        5 => '/^(ZTO|zto)[0-9]{10}$|^[0-9]{12}$/',    // 中通
        6 => '/^[0-9]{10,15}$/',                      // 韵达
        7 => '/^JT[0-9]{10}$|^[0-9]{12}$/',           // 极兔
        8 => '/^[0-9]{13}$|^E[0-9]{13}$/'             // 邮政
    ];

    /** @var array 公共属性，存放快递信息 */
    public $expressData = [];

    /**
     * 根据快递单号生成标准快递数据
     * @param string $trackingNumber 快递单号
     * @throws Client
     */
    public function generateExpressData(string $trackingNumber): bool
    {
        $trackingNumber = preg_replace('/\s+/', '', $trackingNumber);

        foreach (self::TRACKING_RULES as $code => $pattern) {
            if (preg_match($pattern, $trackingNumber)) {
                $this->expressData['tracking_number'] = $trackingNumber;// 快递单号
                $this->expressData['company_code'] = $code;// 公司代码
                $this->expressData['company_name'] = self::COMPANY_ABBR_MAP[$code] ?? '未知';// 公司名称
                $this->expressData['status'] = ExpressStatusEnum::STORED;// 默认状态：1(已入库)
                return true;
            }
        }
        throw new Client(212001,'没有符合的公司');
    }

    /**
     * 生成取件码（整合领域层）
     * @param int $companyCode 区域ID
     * @param array $shelfLayer 区域开放货架层
     * @param int $sequence 自增序号
     * @return array|false 返回取件码和货架数据
     */
    public function generatePickupCode(int $companyCode, array $shelfLayer, int $sequence)
    {
        // 1. 获取公司代号
        $companyPrefix = self::COMPANY_ABBR_MAP[$companyCode] ?? 'OT';
        // 3. 生成日期部分
        $datePart = date('md');
        // 4. 格式化货架层信息（确保两位数）
        $shelfInfo = sprintf('%02d%02d',
            $shelfLayer['shelfno'],
            $shelfLayer['layerno']
        );
        // 5. 格式化序号（3位数字）
        $formattedSeq = str_pad($sequence, 3, '0', STR_PAD_LEFT);
        // 6. 组合最终取件码
        return sprintf('%s%s-%s-%s',
            $companyPrefix,  // SF/JD等
            $shelfInfo,      // 0101
            $datePart,       // 0616
            $formattedSeq    // 001
        );
    }

    /**
     * 获取快递时间段
     * @param array $params
     * @return array
     */
    public function getTimeSlot(array $params): array
    {
        if($params['appt_type']!==0){
            $ids = array_column(filterDeliveryTimes(Config::get('time.deliveryTimes')), 'id');
            $exits = in_array($params['appt_type'], $ids);
            if(!$exits) throw new Client(212001,'当前时间大于预约开始时间，请刷新重新预约');
            $time_slot= Config::get('time.delivery_time_slot')[$params['appt_type']];
            $params['start_time'] = strtotime($time_slot['start_time']);
            $params['end_time'] = strtotime($time_slot['end_time']);
        }else{
            $params['start_time'] =  time();
            $params['end_time'] =   time()+7200;
        }
        return $params;
    }

    /**
     * 构建分页查询快递参数
     * @param array $params
     * @return array
     */
    public function getListCondition(array $params): array
    {
        $where = [];
        // 构建查询条件
        if(isset($params['user_id']))$where[] =['user_id','=',$params['user_id']];
        if(isset($params['user_id']) && $params['status']==ExpressStatusEnum::RESERVED) $where[] = ['status','in','2,3,4,5'];
        if(isset($params['user_id']) && $params['status']==ExpressStatusEnum::RECEIVED)$where[] = ['status','=',ExpressStatusEnum::RECEIVED];
        // 分页参数
        $page = $params['page'] ?? 1;
        $pageSize = $params['pagesize'] ?? 10;
        // 排序参数
        $order = $params['order'] ?? 'id DESC';
        return ['where'=>$where,'page'=> $page,'pageSize'=> $pageSize, 'order'=>$order];
    }

    public function formatLists($params){

    }




}